import asyncio
import random

import pygame

import cfg
from plane.bomb import Bomb
from plane.bullet import Bullet
from plane.enemy import Enemy
from plane.player import Player
from units.uiUtil import playMyBgMusic, drawText

bg = pygame.image.load('plane/img/background.png')
playerImg = pygame.image.load('plane/img/me1.png')
bulletImg = pygame.image.load('plane/img/bullet2.png')
enemyImg = pygame.image.load('plane/img/enemy1.png')
musicGold = pygame.mixer.Sound('plane/bomb.mp3')

class MainPlane:
    def __init__(self, dims, FPS=60):
        self.dims = dims
        self.FPS = FPS
        # 设置背景滚动的参数
        self.bg_y = 0
        self.scroll_speed = 1
        # 子弹生成速率
        self.bullet_frequency = 10
        self.enemy_frequency = 60
        self.bombs = [Bomb() for _ in range(5)]
        self.score = 0

    # 游戏主循环所在函数需要由 async 定义
    async def start(self):
        # 初始化游戏界面（screen）：尺寸、背景色等
        screen = pygame.display.set_mode(self.dims)
        # 显示游戏名称
        pygame.display.set_caption("打飞机")
        # 初始化游戏时钟（clock），由于控制游戏帧率
        clock = pygame.time.Clock()
        # 播放背景音
        playMyBgMusic('assets/music/bg3.mp3')

        # 玩家
        player = Player(playerImg, self.dims, (40, 40), (self.dims[0] / 2, self.dims[1] / 2 + 300))
        # 玩家子弹spriteGroup
        bulletCount = 0
        bulletGroup = pygame.sprite.Group()
        # 敌机组
        enemyCount = 0
        enemyGroup = pygame.sprite.Group()

        # 产生敌机的频率
        frequency = 60

        # 游戏主循环
        while cfg.inGame:
            # 按照给定的 FPS 刷新游戏
            # clock.tick() 函数返回上一次调用该函数后经历的时间，单位为毫秒 ms
            # dt 记录上一帧接受之后经历的时间，单位为秒 m
            # 使用 dt 控制物体运动可以使游戏物理过程与帧率无关
            dt = clock.tick(self.FPS) / 1000.0
            # 使用 asyncio 同步
            # 此外游戏主体代码中不需要再考虑 asyncio
            await asyncio.sleep(0)

            # 游戏事件处理
            # 包括键盘、鼠标输入等
            for event in pygame.event.get():
                # 点击关闭窗口按钮或关闭网页
                if event.type == pygame.QUIT:
                    pygame.quit()
                # 当 game_running 为 False 时，

            # 更新背景图位置
            self.bg_y += self.scroll_speed
            # 如果背景移出屏幕，位置置0
            if self.bg_y >= self.dims[1]: self.bg_y = 0
            # 以背景色覆盖刷新游戏界面,背景向上滚动
            # gameBgImg(screen, bg, 270, self.dims)
            bgImg = pygame.transform.scale(bg, self.dims)
            screen.blit(bgImg, (0, self.bg_y))
            screen.blit(bgImg, (0, self.bg_y-self.dims[1]))

            # 让飞机跟随键盘移动
            keys_pressed = pygame.key.get_pressed()
            if keys_pressed[pygame.K_UP]:
                player.move('up')
            if keys_pressed[pygame.K_DOWN]:
                player.move('down')
            if keys_pressed[pygame.K_LEFT]:
                player.move('left')
            if keys_pressed[pygame.K_RIGHT]:
                player.move('right')
            # 画玩家的飞机
            player.draw(screen)
            # 生成玩家子弹，每隔frequency生成一组
            bulletCount +=1
            if bulletCount>self.bullet_frequency:
                bulletCount = 0
                bulletGroup.add(Bullet(bulletImg, (20, 20), (player.rect.x+player.rect.width/2, player.rect.y)))
            # 将超出屏幕的子弹精灵删除
            for bullet in bulletGroup:
                if bullet.rect.y<0:
                    bulletGroup.remove(bullet)
            bulletGroup.update()
            bulletGroup.draw(screen)

            # 画敌机sprite
            enemyCount += 1
            if enemyCount > self.enemy_frequency:
                enemyCount = 0
                enemyGroup.add(Enemy(enemyImg, (40, 40), (random.randint(0,self.dims[0]-20),0)))
            # 将超出屏幕的敌机删除出
            for enemy in enemyGroup:
                if enemy.rect.y>self.dims[1]:
                    enemyGroup.remove(enemy)
            enemyGroup.update()
            enemyGroup.draw(screen)

            # 开始碰撞检测，
            # 子弹和敌机碰撞，敌机爆炸
            for enemy in enemyGroup:
                blocks_hit_list = pygame.sprite.spritecollide(enemy, bulletGroup, True)
                if blocks_hit_list.__len__()>0:
                    enemyGroup.remove(enemy)
                    self.score += 1
                    # 播放爆炸图
                    for bomb in self.bombs:
                        if not bomb.visible:
                            bomb.set_position(enemy.rect[0], enemy.rect[1])
                            bomb.visible = True
                            break
                    # 播放爆炸音效
                    musicGold.play()
            # 播放爆炸图
            for bomb in self.bombs:
                bomb.acction()
                bomb.draw(screen)

            # 判断玩家的飞机是否和敌机相撞
            gameFail = pygame.sprite.spritecollide(player, enemyGroup, True)
            if gameFail.__len__()>0:
                self.score = 0
                cfg.inGame = False
                return

            # 画得分
            drawText(f"得分：{self.score}", "black", (50,100), screen)

            # 将游戏界面内容输出至屏幕
            pygame.display.update()

        # 跳出游戏主循环，退出游戏
        cfg.inGame = False